#include "KmyStream.h"
#include "KmyMath.h"
#include <cstring>

KmyStream::KmyStream(u8* data, int length)
{
    this->data = data;
    this->length = length;
    this->offset = 0;
}

void KmyStream::finalize(){
    delete[] data;
    length = 0;
    offset = 0;
}

void KmyStream::initialize(u8 *data, int length){
    this->data = data;
    this->length = length;
    this->offset = 0;
}

char KmyStream::getChar(){
    if (offset>length-1){
        return '\0';
    }
    char* c=(char*)(data+offset);
    offset+=1;
    return *c;
}

short KmyStream::getShort(){
    if (ALIGN2(offset)>length-2){
        return 0;
    }
    offset = ALIGN2(offset);
    u8* p = data+offset;
    short *s=(short*)p;
    offset+=2;
    return *s;
}

int KmyStream::getInt(){
    if (ALIGN4(offset)>length-4){
        return 0;
    }
    offset = ALIGN4(offset);
    u8* p = data+offset;
    int *i=(int*)p;
    offset+=4;
    return *i;
}

float KmyStream::getFloat(){
    if (ALIGN4(offset)>length-4){
        return 0;
    }
    offset = ALIGN4(offset);
    u8* p = data+offset;
    float *f=(float*)p;
    offset+=4;
    return *f;
}

// utf 8编码，我想是失败了，直接读取成2进制
// 一行最多255个字节，85个3字节字符
string KmyStream::readLine(){
    if (offset>=length){
        return "";
    }
    char buff[256];
    u8 c = data[offset];
    int index = 0;
    while (offset<length && c<=' '){
        offset++;
        c = data[offset];
    }
    while(offset<length && c!='\n' && c!='\r'){
        buff[index]=c;
        index++;
        offset++;
        c=data[offset];
    }
    if (c=='\n'){
        offset+=1;
    }
    buff[index]=0;
    string str(buff);
    return str;
//    string str("");
//    char *c = (char*)(data+offset);
//    while(offset<length &&
//          (*c>=0 && *c<=' ')){
//        c++;
//        offset++;
//    }
//    while(offset<length && *c!='\n'){
//        str+= *c;
//        c++;
//        offset++;
//    }
//    if (offset<length){
//        offset++;
//    }
//    return str;
}

string KmyStream::readString(){
    if (offset>=length){
        return "";
    }
    char buff[256];
    u8 c = data[offset];
    int index = 0;
    while (offset<length && c<=' '){
        offset++;
        c = data[offset];
    }
    while(offset<length && c>' '){
        buff[index]=c;
        index++;
        offset++;
        c=data[offset];
    }
    buff[index]=0;
    if (offset<length){
        if (c=='\n' || c=='\r'){
            offset+=1;
        }else{
//            offset+=1;
        }
    }
    string str(buff);
    return str;
//    string str("");
//    char *c = (char*)(data+offset);
//    while(offset<length &&
//          (*c<=' ')){
//        c++;
//        offset++;
//    }
//    while(offset<length && (*c<0 || *c>' ')){
//        str+= *c;
//        c++;
//        offset++;
//    }
//    if (offset<length){
//        offset++;
//    }
//    return str;
}

int KmyStream::getOffset(){
    return offset;
}

St_Buff* KmyStream::readLineBuff(){
    if (offset>=length){
        return NULL;
    }
    char buff[256];
    u8 c = data[offset];
    int index = 0;
    while (offset<length && c<=' '){
        offset++;
        c = data[offset];
    }
    while(offset<length && c!='\n' && c!='\r'){
        buff[index]=c;
        index++;
        offset++;
        c=data[offset];
    }
    if (c=='\n'||c=='\r'){
        offset+=1;
    }
    buff[index]=0;
//    string str(buff);
//    return str;
    if (index==0){
        return NULL;
    }
    St_Buff *lb = new St_Buff;
    lb->size = index+1;
    lb->buff = new u8[lb->size];
    memcpy(lb->buff, buff, lb->size);
    return lb;
}

St_Buff* KmyStream::readBuff(int size){
    St_Buff *lb = new St_Buff;
    lb->buff = new u8[size];
    lb->size = size;
    memcpy(lb->buff, data+offset, lb->size);
    offset+=size;
    return lb;
}

St_Buff* KmyStream::readUtf8StringBuff(){
    if (offset>=length){
        return NULL;
    }
    int len = 0;
    while(offset+len<length){
        u8 c = data[offset+len];
        if (c == 0||c=='\n'){
            len+=1;
            break;
        }else if ((c&0x80) == 0){
            len+=1;
        }else if ((c&0xE0) == 0xC0){
            len+=2;
        }else if ((c&0xF0) == 0xE0){
            len+=3;
        }else if ((c&0xF8) == 0xF0){
            len+=4;
        }
    }
//    len+=1;
    St_Buff *sb = new St_Buff;
    sb->buff = new u8[len];
    sb->size = len;
    memcpy(sb->buff, data+offset, len-1);
    sb->buff[len-1]=0;
    offset+=len;
    return sb;
}
